package cn.xuqiudong.sso.client.session.spring;

import cn.xuqiudong.sso.client.session.SessionMappingStorage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.session.SessionRepository;

import javax.servlet.http.HttpSession;
import java.util.concurrent.TimeUnit;

/**
 *  如果客户端使用spring-session-data-redis 管理session的话  （@EnableRedisHttpSession）
 *
 *
 */
public final class SpringRedisSessionMappingStorage implements SessionMappingStorage {

    private static final String SESSION_TOKEN_KEY = "session_token_key_";
    private static final String TOKEN_SESSION_KEY = "token_session_key_";

    /**
     * 超时时间  暂时设为48h FIXME
     */
    private static final long TIMEOUT = 48L;

    @Autowired(required = false)
    private SessionRepository<?> sessionRepository;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public synchronized void addSessionById(final String accessToken, final HttpSession session) {
        stringRedisTemplate.opsForValue().set(SESSION_TOKEN_KEY + session.getId(), accessToken, TIMEOUT, TimeUnit.HOURS);

        stringRedisTemplate.opsForValue().set(TOKEN_SESSION_KEY + accessToken, session.getId(), TIMEOUT, TimeUnit.HOURS);
    }

    @Override
    public synchronized void removeBySessionById(final String sessionId) {
        final String accessToken = stringRedisTemplate.opsForValue().get(SESSION_TOKEN_KEY + sessionId);
        if (accessToken != null) {
            stringRedisTemplate.delete(TOKEN_SESSION_KEY + accessToken);
            stringRedisTemplate.delete(SESSION_TOKEN_KEY + sessionId);
            // 不再删除session, 不然在刷新token的时候会变更session，导致再次登录的情况
            //sessionRepository.deleteById(sessionId);
        }
    }

    @Override
    public synchronized HttpSession removeSessionByMappingId(final String accessToken) {
        final String sessionId = stringRedisTemplate.opsForValue().get(TOKEN_SESSION_KEY + accessToken);
        if (sessionId != null) {
            removeBySessionById(sessionId);
        }
        return null;
    }
}
